<?php

class SJB_Admin_Payment_PaymentLog extends SJB_Function
{
	private $selectedPage;
	private $restore;
	private $action;
	private $sortingField;
	private $itemsPerPage;
	private $sortingOrder;
	private $searchingCriteria;
	private $template;
	private $pagesForViewing = array();
	/**
	 * @var SJB_TemplateProcessor
	 */
	private $templateProcessor;
	/**
	 * @var SJB_SearchFormBuilder
	 */
	private $searchFormBuilder;
	/**
	 * @var SJB_PaymentLogCriteriaSaver
	 */
	private $criteriaSaver;
	/**
	 * @var SJB_PaymentLogSearcher
	 */
	private $searcher;
	public $totalPages;

	public function isAccessible()
	{
		$this->setPermissionLabel('payment_log');
		return parent::isAccessible();
	}
	
	public function execute()
	{
		$this->init();
		$this->dispatch();
	}

	private function init()
	{
		$this->action = SJB_Request::getVar('action', 'search');
		$this->selectedPage = SJB_Request::getVar('page', 1);
		$this->itemsPerPage = SJB_Request::getVar('items_per_page', 50);
		$this->sortingField = SJB_Request::getVar('sorting_field', 'date');
		$this->sortingOrder = SJB_Request::getVar('sorting_order', 'DESC');
		$this->restore = SJB_Request::getVar('restore', false);

		$this->templateProcessor = SJB_System::getTemplateProcessor();
		$this->searcher = new SJB_PaymentLogSearcher($this->selectedPage, $this->itemsPerPage, $this->sortingField, $this->sortingOrder);
		$this->criteriaSaver = new SJB_PaymentLogCriteriaSaver();
		$paymentLogItem = new SJB_paymentLog($_REQUEST);
		$this->searchFormBuilder = new SJB_SearchFormBuilder($paymentLogItem);
		$this->searchingCriteria = $this->searchFormBuilder->extractCriteriaFromRequestData($_REQUEST, $paymentLogItem);
	}

	private function dispatch()
	{
		switch ($this->action) {
			case 'display_message':
				$this->displayItem();
				break;

			case 'search':
				$this->displaySearchResults();
				break;
		}
	}

	private function displayItem()
	{
		$sid = SJB_Request::getVar('sid', false);
		$paymentLogItem = SJB_PaymentLogManager::getPaymentLogInfoBySID($sid);
		$this->templateProcessor->assign('paymentLogItem', $paymentLogItem);
		$this->templateProcessor->display('payment_log_details.tpl');
	}

	private function displaySearchResults()
	{
		$this->initSearchingForm();
		$this->criteriaSaver->setSession($_REQUEST, $this->searcher->getFoundObjectSIDs());
		$foundPaymentLogs = $this->searchLogsFromCriteria();
		$foundPaymentLogs = $this->searchPaymentLogs($foundPaymentLogs);
		$paymentLogsCount = $this->searcher->getAffectedRows();
		$this->totalPages = ceil($paymentLogsCount / $this->itemsPerPage);
		$this->createPagesList();

		$this->assignParametersAndDisplayLog($paymentLogsCount, $foundPaymentLogs);
	}

	private function initSearchingForm()
	{
		if ($this->restore) {
			$this->loadCriteriaAndMergeWithRequest();
		}
		$this->setTemplate('payment_log.tpl');
		$this->displaySearchForm();
	}

	private function loadCriteriaAndMergeWithRequest()
	{
		$_REQUEST = array_merge($_REQUEST, $this->criteriaSaver->getCriteria());
	}

	private function setTemplate($template)
	{
		$this->template = $template;
	}

	private function displaySearchForm()
	{
		$this->searchFormBuilder->setCriteria($this->searchingCriteria);
		$this->searchFormBuilder->registerTags($this->templateProcessor);
		$this->templateProcessor->display("payment_log_search_form.tpl");
	}

	private function searchLogsFromCriteria()
	{
		$order_info = array('sorting_field' => $this->sortingField,
			'sorting_order' => $this->sortingOrder);
		$this->criteriaSaver->setSessionForOrderInfo($order_info);
		$this->criteriaSaver->setSessionForCurrentPage($this->selectedPage);
		$this->criteriaSaver->setSessionForListingsPerPage($this->itemsPerPage);
		return $this->searcher->getObjectsSIDsByCriteria($this->searchingCriteria);
	}

	private function searchPaymentLogs($foundPaymentLogs)
	{
		foreach ($foundPaymentLogs as $id => $paymentLogSID) {
			$paymentLogInfo = SJB_PaymentLogManager::getPaymentLogInfoBySID($paymentLogSID);
			$foundPaymentLogs[$id] = $paymentLogInfo;
		}
		return $foundPaymentLogs;
	}

	private function createPagesList()
	{

		$this->checkRangeAndAddToPagesList(1);
		$this->checkRangeAndAddToPagesList($this->selectedPage - 1);
		$this->checkRangeAndAddToPagesList($this->selectedPage - 2);
		$this->checkRangeAndAddToPagesList($this->selectedPage - 3);
		$this->checkRangeAndAddToPagesList($this->selectedPage);
		$this->checkRangeAndAddToPagesList($this->selectedPage + 1);
		$this->checkRangeAndAddToPagesList($this->selectedPage + 2);
		$this->checkRangeAndAddToPagesList($this->selectedPage + 3);
		$this->checkRangeAndAddToPagesList($this->totalPages);
	}

	private function checkRangeAndAddToPagesList($page)
	{
		$isPageAlreadyAdded = array_search($page, $this->pagesForViewing) !== false;
		if ($isPageAlreadyAdded) {
			return;
		}

		$isPageInRange = $page >= 1 && $page <= $this->totalPages;
		if (!$isPageInRange) {
			return;
		}

		$this->pagesForViewing[] = $page;
	}


	private function getFields()
	{
		$searchFields = '';
		foreach ($_REQUEST as $key => $val) {
			if (is_array($val)) {
				foreach ($val as $fieldName => $fieldValue) {
					$searchFields .= "&{$key}[{$fieldName}]={$fieldValue}";
				}
			}
		}
		return $searchFields;
	}

	private function assignParametersAndDisplayLog($paymentsCount, $found_payments)
	{
		$this->templateProcessor->assign("paymentsCount", $paymentsCount);
		$this->templateProcessor->assign("found_payments", $found_payments);
		$this->templateProcessor->assign("searchFields", $this->getFields());
		$this->templateProcessor->assign("totalPages", $this->totalPages);
		$this->templateProcessor->assign("pages", $this->pagesForViewing);
		$this->templateProcessor->assign("currentPage", $this->selectedPage);
		$this->templateProcessor->assign("items_per_page", $this->itemsPerPage);
		$this->templateProcessor->assign("sorting_field", $this->sortingField);
		$this->templateProcessor->assign("sorting_order", $this->sortingOrder);
		$this->templateProcessor->display('payment_log.tpl');
	}
}